-
Notifications
You must be signed in to change notification settings - Fork 75
Normative: Switch syntax to ??. #48
Conversation
That calls for a celebration! :) |
README.md
Outdated
obj?.prop // optional static property access | ||
obj?.[expr] // optional dynamic property access | ||
func?.(...args) // optional function or method call | ||
obj??.prop // optional static property access |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Align comments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed alignment.
By "conclusion" he meant that this comment has a lot of upvotes. There's nothing official about it and there are other comments with even more 👍 . |
@Mouvedia Something that's somewhat official about it is that the plan to switch to |
Note that there is a parallel change for nullish coalescing at tc39/proposal-nullish-coalescing#23 (to use |
Too many
PS. Compare to my syntax suggestion:
|
@hax Nullish coalescing is a binary operator, so it normally would be written with spaces: const city = staff??.company??.address??.city ??: defaultCity; I think the spacing makes it reasonable to distinguish the operators from each other. As you mentioned in your original comment (#34 (comment)), My reading of #34 is that the four operators in this PR have by far the most support. See #34 (comment) and the comments immediately above and below it for a poll of various alternatives. (And, as mentioned, TC39 seems to be mostly in favor of this syntax, and they're the ones actually making the decision.) Hopefully most people are at least agreed that this is an improvement over the original |
Even with spaces, I still prefer @hax's syntax suggestion, and agree that the similarity between the two operators is rather confusing and doesn't help quick reading / understanding of code. This just looks much more readable to me: const city = staff!.company!.address!.country ?? defaultCity; And so does this: const city = staff?.company?.address?.country ?? defaultCity; |
@claudepache What do you think of this PR? |
I haven’t had time to review it yet. But yes, I'm favourable to switch to that syntax, on condition that the syntax of nullish-coalescing is also changed (tc39/proposal-nullish-coalescing#23 or anything else). |
@alangpierce Coding style can help, but these too close symbols also restrict the options of coding style. For example, you can not also add spaces around
Try two spaces...
Maybe we need three?
...So, see the problem? Note, I just use
And
Unfortunately the supporters all ignore the readability problem of
The thread is already too long to catch. So maybe we should create a new issue. |
Follows the conclusion of the discussion at #34
What conclusion #51 ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some corrections.
Also, given the strong resistance against that syntax, we should probably wait that TC39 confirms whether it is the way to go.
* In order to allow `foo?.3:0` to be parsed as `foo ? .3 : 0` (as required for backward compatibility), a simple lookahead is added at the level of the lexical grammar, so that the sequence of characters `?.` is not interpreted as a single token in that situation (the `?.` token must not be immediately followed by a decimal digit). | ||
### Why two question marks instead of one? | ||
|
||
An earlier version of this proposal used `??.` for the optional chaining operator, with `??[` for dynamic property access and `??(` for optional function/method calls. The switch to two question marks allows for more consistency and the ability to omit the surprising `.` in the latter two cases. See [the past discussion](https://github.com/tc39/proposal-optional-chaining/issues/34) on this topic for more details. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too zealous search-and-replace? Replace back ??.
/ ??[
/??(
with?.
/ ?.[
/ ?.(
in that sentence.
* constructor or template literals in/after an Optional Chain: `new a?.b()`, ``a?.b`{c}` `` | ||
* optional construction: `new a??()` | ||
* optional template literal: ``a??`{b}` `` | ||
* constructor or template literals in/after an Optional Chain: `new a??b()`, ``a??.b`{c}` `` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new a??.b()
@@ -165,28 +166,13 @@ All the above cases will be forbidden by the grammar or by static semantics so t | |||
<dl> | |||
|
|||
|
|||
<dt>obj?.[expr] and func?.(arg) look ugly. Why not use obj?[expr] and func?(arg) as does <language X>? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of deleting that FAQ item, let’s replace it with:
obj??.prop, obj??[expr] and func??(arg) look like null coalescing in <language X>. Why not use obj?.prop, obj?[expr] and func?(arg) as does <language X>?
Further adaptations below.
|
||
<dd> | ||
|
||
We don’t use the `obj?[expr]` and `func?(arg)` syntax, because of the difficulty for the parser to efficiently distinguish those forms from the conditional operator, e.g., `obj?[expr].filter(fun):0` and `func?(x - 2) + 3 :1`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let’s be more affirmative: ”We can’t use...”
|
||
We don’t use the `obj?[expr]` and `func?(arg)` syntax, because of the difficulty for the parser to efficiently distinguish those forms from the conditional operator, e.g., `obj?[expr].filter(fun):0` and `func?(x - 2) + 3 :1`. | ||
|
||
Alternative syntaxes for those two cases each have their own flaws; and deciding which one looks the least bad is mostly a question of personal taste. Here is how we made our choice: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a temporary measure, replace with: ”[TODO: explain the rationale and the tradeoffs behind the choice of ??
]” (and delete the two bullets just below).
@@ -22,7 +22,7 @@ | |||
<h1>Scope</h1> | |||
<p>This is the spec text of the <a href="https://github.com/tc39/proposal-optional-chaining/">Optional Chaining proposal</a> in ECMAScript. </p> | |||
|
|||
<p>For the syntax, we use the `?.` token, with a lookahead at the level of the lexical grammar that allows to discriminate between `a?.b` (optional chaining) and `a?.3:0` (conditional operator, whose meaning cannot be changed due to backward compatibility constraints).</p> | |||
<p>For the syntax, we use the `??.` token. An earlier version of this proposal used `?.`</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact, we use three tokens, namely ??.
, ??[
and ??(
. I propose (don’t hesitate to improve the text):
For the syntax, we use the
??
sequence of characters for suggesting ”optional”. An earlier version of this proposal used the?.
token for that purpose.
|
||
RightBracePunctuator :: | ||
`}` | ||
`??.` `??(` `??[` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be surrounded by <ins>.
OptionalChainingPunctuator Arguments[?Yield, ?Await] | ||
`??[` Expression[+In, ?Yield, ?Await] `]` | ||
`??.` IdentifierName | ||
`??(` ArgumentsList[?Yield, ?Await] `,`? `) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You missed ??()
; that is to say, ArgumentsList is optional, but the optional comma is forbidden if ArgumentsList is omitted:
`??(` `)`
`??(` ArgumentList[?Yield, ?Await] `,`? `)`
OptionalChain : | ||
`??(` ArgumentsList? `)` | ||
</emu-grammar> | ||
<emu-grammar>OptionalChain : `??(` ArgumentsList `,` `)` </emu-grammar> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’d say (as above):
<emu-grammar>
OptionalChain :
`??(` `)`
`??(` ArgumentList[?Yield, ?Await] `,`? `)`
</emu-grammar>
@@ -652,7 +642,7 @@ <h1>Expression Rules</h1> | |||
</emu-alg> | |||
<emu-grammar> | |||
OptionalChain : | |||
OptionalChainingPunctuator Arguments | |||
`??(` ArgumentsList `,`? `)` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above.
OptionalChain :
`??(` `)`
`??(` ArgumentsList `,`? `)`
OptionalChain Arguments
Are we seriously considering ??. and ??: as better than ?. and ?? for his proposal? I don't know where anyone is seeing a consensus that ??. is more desired or accepted than ?. by the community at large. In fact, it seems that ?. is far more accepted based on #51. I find ??. to be very heavy and unsightly, and in all honesty don't really want to be writing code littered with this verbose operator... |
I've commented in the other thread, but I have to say, this PR and the direction this proposal is now taking is very, very concerning. Ergonomics, understandability, verbosity. We are starting to head in the wrong direction on all fronts, and I truly hope this PR does not get merged. |
@littledan If you still think that this PR should be merged, could you apply the requested changes? |
I don't know that the debate over the operator has been settled. At this time, it still appears as though, despite it's supposed inconsistency, ?./?? is still by far the more preferred operator. Discussions on the operators seem to have stalled, but I don't believe that means the debate has ended, nor that ??. is what we should be using. |
I presented both options to the committee last week and strongly advocated for the current syntax, calling out the strong community support. Both proposals had hard vetoes that prevented stage advancement:
Paring back the proposal to only support There was no strong opposition to Looking at the poll results for possible token options, there are really only two options and we've definitively ruled out one. I suspect that hard constraints settle the syntax debate, but I'm open to alternatives. |
Is there a good place for discussion? Eg; I am curious what made |
@rattrayalex Some people didn't like the colon. Not sure what more there is to say; I guess it makes it less analogous to |
Cool, thanks @littledan. Perhaps they could be persuaded (much of es syntax design seems very constraint-driven). I assume you're working with the fine folks over at optional chaining. May be worth opening an informal bikeshed poll over on the other repo. |
43b52dd
to
6805300
Compare
IMO null coalescing should be ||| as it's the only one that makes intuitive sense and leaves open the possibility to an &&& operator where 0 and the empty string are considered truthy. That would also open up |
@selipso in the TC39 meeting this week it was brought up that if |
Then by that logic Since we have only one point of reference for this syntax ( With |
@selipso I think we should learn from failure of visually too close operators. The mainstream coding style now only allow Note we can forbidden |
@hax I, for one, would be fine with This would also free up optional chaining (which IMO is a more exciting and practical language feature) to use either |
@hax There are definitely valid current uses of ==, and not all == should nor could be converted to === and still maintain the desired functionality. I commonly use |
@jrista No. All valid use cases of But |
@hax It may be that you can, one way or another, find a way to eliminate ALL I find value in I guess I try to be pragmatic rather than dogmatic when it comes to which operator to use. When I use |
If you add comments for every
You may think me (and many) as "dogmatic", we can argue it in other place (we already offtopic in this issue) but that's the real problem in collaboration. In a big team, you have to consider the cost of communication. |
@hax: I would not simply do The "cost" of communication is not very large when it is a comment right in the code, right where it needs to be. |
A developer who would think it’s safe to casually remove an explicit type coercion likely would also casually remove a comment, believing it to be irrelevant :-) |
I do not like the change to |
@0rvar, I believe it was already decided to seek stage advancement with the current spec. The current spec uses ?. This is a summary of issues I've read over the months. |
I think many of us are leaning more towards |
Follows the conclusion of the discussion at
#34